from PyQt4 import QtGui, QtCore
import osg2
import OpenGL.GL
import lucid.core
from lucid.util.qt.property_tree import *
from pydispatch import dispatcher

import lucid.plugins.field_editors.field_editors as field_editors


class SHLPropertyGroup(PropertyGroup, lucid.core.IFcEditorGroupPlugin):
   @staticmethod
   def getSupportedFcTypes():
      return ["SHLParameterChunk","SHLChunk"]
      
   def __init__(self, parent, fc):
      super(SHLPropertyGroup,self).__init__("SHLPropGroup", parent)
      self.mFC = fc
      self.name = fc.getType().getCName()
      self.externalEditorType = None            
      
      # Fill in the editors using generics
      field_editors.addGenericFCProperties(self, fc)
      
      # Add editors for all parameters
      parameters = fc.getParameters()
      for p in parameters:
         self.addChild(self.createShaderPropField(p))
      

   def createShaderPropField(self, p):
      """ Create a field editor for param: p """
      field_prop = None
      p_type = type(p)
      if p_type in [osg2.ShaderParameterBool]:
         field_prop = field_editors.BoolProperty(self,p,"value")
      elif p_type in [osg2.ShaderParameterVec2f, 
                      osg2.ShaderParameterVec3f, 
                      osg2.ShaderParameterVec4f]:
         field_prop = field_editors.VectorProperty(self,p,"value")
      elif p_type in [osg2.ShaderParameterReal, 
                      osg2.ShaderParameterInt]:
         field_prop = field_editors.NumberProperty(self,p,"value")
      elif p_type in [osg2.ShaderParameterString]:
         field_prop = field_editors.StringProperty(self,p,"value")
      elif p_type in [osg2.ShaderParameterMatrix]:
         field_prop = field_editors.DumbFieldProperty(self,p,"value")
      else:
         print "Unknown shader param type [%s] for param: %s"%(str(p_type),p.getName())
            
      field_prop.name = p.getName()
      field_prop.setEditableName(p.getName, p.setName)
      
      return field_prop
      
      
   def hasEditor(self,index):
      if index.column() == 0:
         return False
      return True   
   
   
   # --- Custom editor for case where we have external editing --- #
   def createEditor(self, parent, option, index):
      editor = QtGui.QWidget(parent)
      self.hlayout = QtGui.QHBoxLayout(editor)
      self.hlayout.setMargin(0)
      self.hlayout.setSpacing(0)
      
      spacer = QtGui.QSpacerItem(40,10,QtGui.QSizePolicy.Expanding,QtGui.QSizePolicy.Minimum)
      self.hlayout.addItem(spacer)
      
      sub_btn = QtGui.QToolButton(editor)
      sub_btn.setIcon(QtGui.QIcon(":/icons/data/icons/list-remove_16.png"))
      self.hlayout.addWidget(sub_btn)
      add_btn = QtGui.QToolButton(editor)
      add_btn.setIcon(QtGui.QIcon(":/icons/data/icons/list-add_16.png"))
      self.hlayout.addWidget(add_btn)
      
      add_btn.connect(add_btn, QtCore.SIGNAL("pressed()"), self.onAddParam)
      sub_btn.connect(sub_btn, QtCore.SIGNAL("pressed()"), self.onDelParam)
      return editor
   
   def onOpenEditor(self):
      print "Open editor"
      self.externalEditor = self.externalEditorType(self.mFC)
   
   def onAddParam(self):
      param_types = [osg2.ShaderParameterBool, osg2.ShaderParameterInt, osg2.ShaderParameterReal,
                     osg2.ShaderParameterVec2f, osg2.ShaderParameterVec3f, osg2.ShaderParameterVec4f,
                     osg2.ShaderParameterString]
      self._add_calls = []
      add_menu = QtGui.QMenu("Add")
      for pt in param_types:
         add_call = lambda ptype=pt: self.createParameter(ptype)
         self._add_calls.append(add_call)
         add_menu.addAction(pt.__name__, add_call)      
      add_menu.exec_(QtGui.QCursor.pos())

   def createParameter(self, paramType):
      new_param = paramType.create()
      self.mFC.addParameter(new_param)
      self.getModel().reset()           # XXX: Make this smarter
      
   def onDelParam(self):
      params = self.mFC.getParameters()
      self._del_calls = []
      del_menu = QtGui.QMenu("Remove")
      for p in params:
         rem_call = lambda param=p: self.removeParameter(param)
         self._del_calls.append(rem_call)
         del_menu.addAction(p.getName(), rem_call)
      
      del_menu.exec_(QtGui.QCursor.pos())
   
   def removeParameter(self, param):
      self.mFC.subParameter(param)
      self.getModel().reset()           # XXX: Make this smarter
   
   
 